﻿using EMS.system.Entityies.MasterData.MaterialManagementModel;
using EMS.system.Entityies.MasterData.MaterialTypeModel;
using EMS.system.Entityies.MasterData.SupplierManagementModel;
using EMS.system.Entityies.WarehouseManagement.LvnventoryOnhandModel;
using EMS.system.IEntityAppService.MasterData.LvnventoryOnhandService;
using EMS.system.IEntityAppService.MasterData.LvnventoryOnhandService.LvnventoryOnhandDTO;
using ServiceStack.Script;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Dynamic.Core;
using System.Text;
using System.Threading.Tasks;
using Volo.Abp.Application.Services;
using Volo.Abp.Domain.Repositories;

namespace EMS.system.EntityAppService.MasterData.LvnventoryOnhandService
{
    public class LvnventoryOnhandAppService:ApplicationService,ILvnventoryOnhandAppService
    {
        /// <summary>
        /// 库存现有量仓储
        /// </summary>
        private readonly IRepository<LvnentoryOnhand,int> _inventoryOnhandRepository;
        /// <summary>
        /// 供应商管理仓储
        /// </summary>
        private readonly IRepository<SupplierManagement,int> _supplierManagementRepository;
        /// <summary>
        /// 物料管理仓储
        /// </summary>
        private readonly IRepository<MaterialManagement, int> _materialManagementRepository;
        /// <summary>
        /// 物料类型仓储
        /// </summary>
        private readonly IRepository<MaterialType,int> _materialTypeRepository;
        /// <summary>
        /// 构造函数
        /// </summary>
        /// <param name="inventoryOnhandRepository"></param>
        public LvnventoryOnhandAppService(IRepository<LvnentoryOnhand, int> inventoryOnhandRepository, IRepository<SupplierManagement, int> supplierManagementRepository, IRepository<MaterialManagement, int> materialManagementRepository, IRepository<MaterialType, int> materialTypeRepository)
        {
            _inventoryOnhandRepository = inventoryOnhandRepository;
            _materialManagementRepository = materialManagementRepository;
            _supplierManagementRepository = supplierManagementRepository;
            _materialTypeRepository = materialTypeRepository;
        }
        /// <summary>
        /// 获取物料类型列表
        /// </summary>
        /// <returns></returns>
        public async Task<List<MaterialTypeTreeDTO>> GetMaterialTypeTree()
        {
            List<MaterialType> materialTypes = await _materialTypeRepository.GetListAsync();
            List<MaterialTypeTreeDTO> materialTypeDtos = MaterialTypeDiGui(materialTypes,0);
            return materialTypeDtos;
        }
        /// <summary>
        /// 递归
        /// </summary>
        /// <param name="materialTypes"></param>
        /// <param name="pid"></param>
        /// <returns></returns>
      
        public List<MaterialTypeTreeDTO> MaterialTypeDiGui(List<MaterialType> materialTypes, int pid)
        {
            var materialType = materialTypes.Where(x => x.ParentId == pid).ToList(); // 确保转为列表  
            List<MaterialTypeTreeDTO> materialTypeDtos = new List<MaterialTypeTreeDTO>();

            foreach (MaterialType materialType1 in materialType)
            {
                MaterialTypeTreeDTO materialTypeTreeDTO = new MaterialTypeTreeDTO();
                materialTypeTreeDTO.Id = materialType1.Id;
                materialTypeTreeDTO.title = materialType1.MaterialTypeName;

                // 这里确保 pid 合理，避免无限递归  
                materialTypeTreeDTO.children = MaterialTypeDiGui(materialTypes, materialType1.Id);

                materialTypeDtos.Add(materialTypeTreeDTO);
            }

            return materialTypeDtos;
        }
        /// <summary>
        /// 获取库存现有量显示 分页 查询
        /// </summary>
        /// <param name="pageIndex"></param>
        /// <param name="pageSize"></param>
        /// <param name="materialCode"></param>
        /// <param name="warehouse"></param>
        /// <returns></returns>
        public async Task<PagedResult> GetLvnventoryOnhandList(int pageIndex,int pageSize,string ? materialCode,string ? warehouse)
        {
            var predicate = PredicateBuilder.New<LvnentoryOnhand>(true);
            if (!string.IsNullOrEmpty(materialCode))
            {
                predicate=predicate.And(m=>m.MaterialCode .Contains( materialCode));
            }
            if (!string.IsNullOrEmpty(warehouse))
            {
                predicate = predicate.And(m => m.Warehouse.Contains(warehouse));
            }
            var lvnventoryOnhand = from a in _materialManagementRepository.GetListAsync().Result
                                    join b in  _inventoryOnhandRepository.GetListAsync().Result on a.MaterialCode equals b.MaterialCode
                                    join c in _supplierManagementRepository.GetListAsync().Result on b.SupplierManagementCode equals c.SupplierManagementCode
                                    select new LvnventoryOnhandDTO
                                    {
                                        Id = b.Id,
                                        MaterialCode=a.MaterialCode,
                                        InstockNum = b.InstockNum,
                                        Unit=b.Unit,
                                        LbounNumber = b.LbounNumber,
                                        Warehouse=b.Warehouse,
                                        ReservoirArea=b.ReservoirArea,
                                        BinLocation=b.BinLocation,
                                        ProductionWorkOrders=b.ProductionWorkOrders,
                                        LbounTime=b.LbounTime,
                                        LvnventoryTime = b.LvnventoryTime,
                                        IsFreeze=b.IsFreeze,
                                        MaterialName=a.MaterialName,
                                        SpecificationsModels=a.SpecificationsModels,
                                        SupplierManagementCode=c.SupplierManagementCode,
                                        SupplierName=c.SupplierName,
                                        SupplierAbbreviation=c.SupplierAbbreviation,
                                    };
            var dto = await _inventoryOnhandRepository.GetListAsync(predicate);
            PagedResult result = new PagedResult();
            result.PageCount = (int)Math.Ceiling((double)(lvnventoryOnhand.Count() == 0 ? 1 : lvnventoryOnhand.Count())/pageSize);
            result.PageSize = pageSize;
            result.CurrentPage = pageIndex;
            result.RowCount=lvnventoryOnhand.Count();
            result.Queryable = lvnventoryOnhand.Skip((pageIndex - 1) * pageSize).Take(pageSize).AsQueryable();
            return result;
        }

    }
}
